package com.hj.tools.tree;

import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author < a href="huajian2018@aliyun.com">hj</ a>
 * @Description 树操作工具
 */
public class TreeUtil {

    /**
     * 获得指定节点下所有归档
     *
     * @param treeNodes 传入的树节点集
     * @param parentId  节点父级ID
     * @return 树节点集
     */
    public static <T extends TreeNode> List<T> build(List<T> treeNodes, Long parentId) {
        List<T> trees = new ArrayList<>();
        for (T treeNode : treeNodes) {
            //判断对象是否为根节点
            if (null == treeNode.getParentId() || treeNode.getParentId().equals(parentId)) {
                //该节点为根节点,开始递归 //通过递归为节点设置childList
                recursionFn(treeNodes, treeNode);
                trees.add(treeNode);
            }
        }

        return trees;
    }

    /**
     * 递归列表
     * 通过递归,给指定treeNode节点设置children
     *
     * @param treeNodes 树集合
     * @param treeNode  单树
     */
    public static <T extends TreeNode> void recursionFn(List<T> treeNodes, T treeNode) {
        //只能获取当前treeNode节点的子节点集,并不是所有子节点集
        List<T> children = getChildList(treeNodes, treeNode);
        //设置他的子集对象集
        //第一种解决方案
        //treeNode.setChildren(CastUtils.cast(children) );
        //第二种解决方案
        //treeNode.setChildren((List<TreeNode>) children);
        //第三种解决方案
        treeNode.setChildren(castList(children, TreeNode.class));

        //迭代子集对象集 //遍历完,则退出递归
        for (T nextChild : children) {
            //判断子集对象是否还有子节点
            if (!CollectionUtils.isEmpty(children)) {
                //有下一个子节点,继续递归
                recursionFn(treeNodes, nextChild);
            }
        }
    }

    /*
     * 将object转成特定类型的list
     */
    private static <T> List<T> castList(Object obj, Class<T> clazz) {
        List<T> result = new ArrayList<>();
        if (obj instanceof List<?>) {
            for (Object o : (List<?>) obj) {
                result.add(clazz.cast(o));
            }
            return result;
        }
        return null;
    }

    /**
     * 获得指定节点下的所有子节点
     *
     * @param list 树集合
     * @param t    单树
     * @return 树集
     */
    public static <T extends TreeNode> List<T> getChildList(List<T> list, T t) {
        List<T> childList = new ArrayList<>();
        //遍历集合元素,如果元素的parentId==指定元素的id,则说明是该元素的子节点
        for (T t1 : list) {
            if (null != t1.getParentId() && t1.getParentId().equals(t.getId())) {
                childList.add(t1);
            }
        }
        return childList;
    }

    /**
     * 判断是否还有下一个子节点
     *
     * @param list 树集合
     * @param t    单树
     */
    public static <T extends TreeNode> boolean hasChild(List<T> list, T t) {
        return getChildList(list, t).size() > 0;
    }


    public static void main(String[] args) {
        Object obj = getObj();
        List<String> list = castList(obj, String.class);
        list.forEach(System.out::println);
    }

    public static Object getObj() {
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("ab");
        return list;
    }


}


/**
 * 两层循环建树
 *
 * @param treeNodes 传入的树节点集
 * @param root      根id
 * @param <T>       类型
 * @return 数据集
 */
    /*public static <T extends TreeNode> List<T> build(List<T> treeNodes, String root) {
        List<T> trees = new ArrayList<>();
        for (T treeNode : treeNodes) {
            if (root.equals(treeNode.getParentId())) {
                trees.add(treeNode);
            }

            for (T ct : treeNodes) {
                if (ct.getParentId().equals(treeNode.getId())) {
                    if (null == treeNode.getChildren()) {
                        treeNode.setChildren(new ArrayList<>());
                    }
                    treeNode.add(ct);
                }
            }
        }
        return trees;
    }*/
